package com.huawei.java.main.client;

import com.huawei.java.main.server.ServerBandwidth;
import com.huawei.java.main.server.ServerClientQos;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author dengguoli
 * @date 2022/3/16
 * @since jdk1.8
 */
public class ClientDemand {

    // 客户端按序全部名称
    private String[] clientName;

    // 客户端可以分配的数量
    private Integer[] serverSize;

    // 整体最大需求
    private Integer[] maxClientDemand;

    // 客户端每个时刻能【得到的总流量】
    private Map<String, Long> clientBandWidth;

    // 按序全部需求
    private EachDemand[] allClientDemand;

    // clientServerQosList
    private ServerClientQos serverClientQos;

    // serverBandwidth
    private ServerBandwidth serverBandwidth;

    public Integer[] getMaxClientDemand() {
        return maxClientDemand;
    }

    public void setMaxClientDemand(Integer[] maxClientDemand) {
        this.maxClientDemand = maxClientDemand;
    }

    public Integer[] getServerSize() {
        return serverSize;
    }

    public void setServerSize() {
        this.serverSize = new Integer[clientName.length-1];
        for (int i = 0; i < clientName.length; i++) {
            // 能够处理的服务器数量
            int size = serverClientQos.getClientServerQosList().get(clientName[i]).size();
            serverSize[i] = size;
        }
    }

    // 客户端名称和得到流量映射
    public Map<String, Long> getClientBandWidth() {
        return clientBandWidth;
    }

    public ServerBandwidth getServerBandwidth() {
        return serverBandwidth;
    }

    public void setServerBandwidth(ServerBandwidth serverBandwidth) {
        this.serverBandwidth = serverBandwidth;
    }

    public ServerClientQos getServerClientQos() {
        return serverClientQos;
    }

    public void setServerClientQos(ServerClientQos serverClientQos) {
        this.serverClientQos = serverClientQos;
    }

    public ClientDemand(List<String[]> csvFile) {
        this.clientName = Arrays.copyOfRange(csvFile.get(0), 1, csvFile.get(0).length);
        this.allClientDemand = this.parseCsvFile(csvFile);
    }

    // 从csv中解析得到
    private EachDemand[] parseCsvFile(List<String[]> csvFile) {
        EachDemand[] eachDemands = new EachDemand[csvFile.size()-1];
        Long maxTotalDemand = 0L;
        int maxTotalIndex = 0;
        for (int i = 1; i < csvFile.size(); i++) {
            EachDemand eachDemand = new EachDemand();
            eachDemand.setEachClientDemand(Arrays.copyOfRange(csvFile.get(i), 1, csvFile.get(0).length));
            if (maxTotalDemand < eachDemand.getTotalDemand()) {
                // 得到最大需求
                maxTotalDemand = eachDemand.getTotalDemand();
                maxTotalIndex = i-1;
            }
            eachDemand.setDemandIndex(i-1);
            eachDemands[i-1] = eachDemand;
        }
        // 设置 最大 基线 Demand
        this.setMaxClientDemand(eachDemands[maxTotalIndex].getEachClientDemand());
        return eachDemands;
    }

    public String[] getClientName() {
        return clientName;
    }

    public void setClientName(String[] clientName) {
        this.clientName = clientName;
    }

    public EachDemand[] getAllClientDemand() {
        return allClientDemand;
    }

    public void setAllClientDemand(EachDemand[] allClientDemand) {
        this.allClientDemand = allClientDemand;
    }

    // 每个客户端能得到的供应
    public Map<String, Long> eachClientBandwidth() {
        Map<String, Long> result = new HashMap<>(clientName.length);
        Map<String, Set<String>> clientServerQosList = this.serverClientQos.getClientServerQosList();
        clientServerQosList.forEach((client, servers) ->{
            AtomicReference<Long> sum = new AtomicReference<Long>(0L);
            servers.forEach((server) -> {
                Integer integer = this.serverBandwidth.getServerBandMap().get(server);
                sum.updateAndGet(v -> v + integer);
            });
            result.put(client, sum.get());
        });
        return result;
    }

    public void setClientBandWidth() {
        this.clientBandWidth = this.eachClientBandwidth();
    }

    // 每个时间点的全部需求，按照clientName顺序排列
    public class EachDemand {
        // 请求序号顺序
        Integer demandIndex;

        // 每次客户端的请求
        Integer[] eachClientDemand;

        // 每次客户端请求总和，后续可以排序调整
        Long totalDemand;

        public Long getTotalDemand() {
            return totalDemand;
        }

        public void setTotalDemand(Long totalDemand) {
            this.totalDemand = totalDemand;
        }

        public Integer getDemandIndex() {
            return demandIndex;
        }

        public void setDemandIndex(Integer demandIndex) {
            this.demandIndex = demandIndex;
        }

        public Integer[] getEachClientDemand() {
            return eachClientDemand;
        }

        public void setEachClientDemand(Integer[] eachClientDemand) {
            this.eachClientDemand = eachClientDemand;
        }

        public void setEachClientDemand(String[] csvInputs) {
            Integer[] eachClientDemand = new Integer[csvInputs.length];
            Long total = 0L;
            for (int i = 0; i < csvInputs.length; i++) {
                eachClientDemand[i] = Integer.valueOf(csvInputs[i]);
                total += eachClientDemand[i];
            }
            this.setTotalDemand(total);
            this.eachClientDemand = eachClientDemand;
        }
    }
}
